﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericList
{
    public class GenericList<T>
    {
        private const int capacity = 4;
        private T[] arr;
        private int count=0;
        private int newCapacity=4;

        //constructors
        public GenericList()
            : this(capacity)
        {
        }
        public GenericList(int capacity)
        {
            arr = new T[capacity];
        }

        //properties
        public int Count
        {
            get{ return this.count;}
        }
        public T[] Arr
        {
            get { return this.arr; }
            set { this.arr = value; }
        }

        //methods
        public void AddElement(T element)
        {
            if (count>=arr.Length)
            {
                GrowCapacity(); 
            }
            this.arr[count]=element;
            count++;
        }

        public T GetElement(int index)
        {
            if (index>=arr.Length)
            {
                throw new IndexOutOfRangeException("The list capacity was exceeded."); 
            }
            return this.arr[index];
        }

        public void DeleteElement(int index)
        {
            if (index >= arr.Length)
            {
                throw new IndexOutOfRangeException("The list capacity was exceeded.");
            }
           T[] newArr=new T[arr.Length];
           for (int i = 0, j = 0; i < arr.Length-1; i++, j++)
           {
               if (i != index)
               {
                   newArr[j] = this.arr[i];
               }
               else
               {
                   newArr[j] = this.arr[i + 1];
                   i++;
               }
           }
           count--;
           this.arr = newArr;
        }
        public void InsertElement(int index, T elem)
        {
            if (index >= arr.Length || arr.Length == newCapacity)
            {
                GrowCapacity();
            }
            T[] newArr = new T[newCapacity + 1];
            for (int i = 0, j = 0; i < arr.Length; i++, j++)
            {
                if (j != index)
                {
                    newArr[j] = this.arr[i];
                }
                else
                {
                    newArr[j] = elem;
                    i--;
                }
            }
            Array.Copy(newArr, this.arr, this.arr.Length);
        }

        public  void Clear()
        {
            Array.Clear(arr,0,arr.Length);
        }

        public int FindIndex(T value)
        {
           int index= Array.BinarySearch(arr,value);
           return index;
        }

        public override string ToString()
        {
            StringBuilder arrToString = new StringBuilder();
            for (int i = 0; i < arr.Length; i++)
            {
                arrToString.Append(arr[i] + " ");
            }
            return arrToString.ToString();
        }
        public void GrowCapacity()
        {
            this.newCapacity = this.arr.Length * 2;
            T[] newArr=new T[newCapacity];
            Array.Copy(this.arr, newArr, this.arr.Length);
            this.arr = newArr;
        }
    }
}
